package com.yonyou.brigade.third_parties.yihao.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.order_center.service.*;
import com.yonyou.brigade.third_parties.yihao.constants.YihaoConstants;
import com.yonyou.brigade.order_center.model.CLYHConfig;
import com.yonyou.brigade.third_parties.yihao.service.ICLYHOrderService;
import com.yonyou.brigade.order_center.util.YHUtils;
import com.yonyou.brigade.util.resultutil.HttpSendUtils;
import com.yonyou.brigade.ybz.service.IConvertService;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import com.yonyou.ybzboot.starter.mongodb.dao.IMongoDao;
import com.yonyou.ybzboot.starter.mongodb.model.CriteriaMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CLYHOrderServiceImpl implements ICLYHOrderService {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${yihao.url.orderurl}")
    private String ORDER_URL;

    @Value("${yihao.tradetype}")
    private String yihaoTradeType;

    @Value("${cnv.baigade.system.code}")
    private String systemCode;

    @Value("${cnv.register.userId}")
    private String cnvRegisterUserId;

    @Value("${cnv.register.tenant}")
    private String cnvRegisterTenant;

    @Value("${cnv.register.cookie}")
    private String cnvRegisterCookie;

    @Autowired
    @Qualifier("briChannelServiceImpl")
    private IBriChannelService briChannelService;

    @Autowired
    @Qualifier("convertServiceImpl")
    private IConvertService convertService;

    @Autowired
    @Qualifier("briOrderServiceImpl")
    private IBriOrderService briOrderService;

    @Autowired
    private YHUtils yHUtils;

    @Autowired
    private IMongoDao mongoDao;

    @Override
    public void getOrderList(String tenant, String orgPk, String beginDate, String endDate, BriChannel briChannel) {
        CLYHConfig channelConfig = (CLYHConfig) briChannelService.getChannelConfig(tenant, ChannelEnum.CLYH.getName(), orgPk, new CLYHConfig());
        Map<String,Object> paramsMap = new HashMap<>();
        Map<String,Object> data = new HashMap<>();
        String requestid = orgPk + String.valueOf(System.currentTimeMillis());
        String version = channelConfig.getVersion();
        if (channelConfig == null) {
            return;
        }
        JSONObject config = convertToJSON(channelConfig);
        String token = yHUtils.getToken(tenant, requestid, config);
        paramsMap.put("access_token",token);
        Integer pageIndex = 1;
        Integer pageSize = 500;
//        data.put("tradeEndTime",endDate);
//        data.put("tradeStartTime",beginDate);
        data.put("modifyStartingTime",beginDate);
        data.put("modifyEndTime",endDate);
        boolean flag = true;
        while (flag) {
            //绿城的接口是定制的，与其他租户接口参数不同
            if (!"x0tc1f2v".equals(tenant)) {
                data.put("pageIndex", pageIndex);
                data.put("pageSize", pageSize);
//                data.put("isQueryAll", 1);//传1查询所有订单，不传默认查询因公
            }
            paramsMap.put("data",data);
            paramsMap.put("requestid",requestid);
            paramsMap.put("version",version);
            logger.info("拉单>>>" + this.ORDER_URL + "参数>>" + JSONObject.toJSONString(paramsMap));
            String result = HttpSendUtils.sendPost(ORDER_URL, JSON.toJSONString(paramsMap));
            logger.info("拉单结果>>>" + result);
            if (!StringUtils.isEmpty(result)) {
                JSONObject response = JSONObject.parseObject(result);
                JSONArray orders = null;
                if (response.getBoolean("successful")) {
                    orders = response.getJSONArray("data");
                    //若拉到的订单为空，则重新拉单，最多拉三次（此方法是补偿机制，差旅壹号的拉单接口有时会有问题）
                    orders = try3TimesIfOrderIsNull(paramsMap, orders);
                    if (orders != null && orders.size() > 0){
                        //拉到差旅壹号订单，调转换接口，获得数据后存入订单中心
                        convertAndSaveOrders(tenant, briChannel, orders);
                        if (orders.size() == pageSize) {
                            pageIndex++;
                        } else {
                            flag = false;
                        }
                    } else {
                        flag = false;
                    }
                } else {
                    flag = false;
                }
            } else {
                flag = false;
            }
        }
    }

    private JSONArray try3TimesIfOrderIsNull(Map<String, Object> paramsMap, JSONArray orders) {
        String result;
        JSONObject response;
        Boolean flag = true;
        while (flag) {
            //如果拉单返回data为空，连续查三次
            if (orders == null || orders.size() == 0) {
                for (int i = 0; i < 3; i++) {
                    result = HttpSendUtils.sendPost(ORDER_URL, JSON.toJSONString(paramsMap));
                    if (!StringUtils.isEmpty(result)) {
                        response = JSONObject.parseObject(result);
                        if (response.getBoolean("successful")) {
                            orders = response.getJSONArray("data");
                            if (orders != null && orders.size() > 0) {
                                flag = false;
                                break;
                            }
                        }
                    }
                }
                flag = false;
            }
            flag = false;
        }
        return orders;
    }

    private void convertAndSaveOrders(String tenant, BriChannel briChannel, JSONArray orders) {
        for (int i = 0; i < orders.size(); i++) {
            JSONObject order = orders.getJSONObject(i);
            // 当在开通配置中配置前台自付订单不拉取时，此类订单过滤掉不做保存
            if ("前台自付".equals(order.getString("payTypeName")) && briChannel.getHotelReceptionPayBySelf() == BriChannel.NOHOTELRECEPTIONPAYBYSELF) {
                continue;
            }
            //订单号
            String orderNo = order.getString("orderId") + "_" + order.getString("passengerStaffNo");
            logger.info("订单转换记事数据，"+ this.yihaoTradeType +"，"+this.systemCode + "，" + this.cnvRegisterUserId + "，" + this.cnvRegisterTenant + "，" + this.cnvRegisterCookie + ">>" + JSONObject.toJSONString(order));
            JSONObject res = convertService.convert(yihaoTradeType, systemCode, cnvRegisterUserId, cnvRegisterTenant, cnvRegisterCookie, order);
            logger.info("订单转记事结果："+ res);
            if (res.getBoolean("success")){
                JSONArray results = res.getJSONArray("result");
                if (results != null && results.size() > 0){
                    for (int j = 0; j < results.size(); j++) {
                        JSONObject jsonObject = results.getJSONObject(j);
                        JSONObject orderCenter = JSON.parseObject(jsonObject.getString("data"));
                        //只有绿城的category字段使用elvxing，其他使用差旅壹号的租户均使用yihao
                        if (!"x0tc1f2v".equals(tenant) && !StringUtils.isEmpty(orderCenter.getString("category"))
                                && orderCenter.getString("category").contains("elvxing")) {
                            String replace = orderCenter.getString("category").replace("elvxing", "yihao");
                            orderCenter.put("category", replace);
                        }
                        if (orderCenter != null && orderCenter.size() > 0 && (!StringUtils.isEmpty(orderCenter.getString("orderNo")) || !StringUtils.isEmpty(orderCenter.getString("orderNO")))){
                            if (StringUtils.isEmpty(order.getString("productTypeName"))) {
                                logger.info("订单号为 "+orderNo+"，出行人为 "+order.getString("passengersName")+" 的订单非酒店，机票，火车票订单，故没有存到订单中心");
                            }else if ("国内酒店".equals(order.getString("productTypeName")) || "国际酒店".equals(order.getString("productTypeName"))){
                                try {
                                    dealWithMongo(order.getString("orderId"), YihaoConstants.HOTEL_MONGO_ORDER_TABLENAME, order);
                                    briOrderService.saveHotel(orderCenter, orderNo, tenant, orderCenter.getString("userId"), ChannelEnum.CLYH.getName(), briChannel.getId());
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                    logger.error("差旅壹号酒店订单存入订单中心时，设置离店日期时出现错误");
                                }
                            }else if ("国内机票".equals(order.getString("productTypeName")) || "国际机票".equals(order.getString("productTypeName"))){
                                try {
                                    dealWithMongo(order.getString("orderId"), YihaoConstants.FLIGHT_MONGO_ORDER_TABLENAME, order);
                                    briOrderService.saveFlight(orderCenter, orderNo, tenant, orderCenter.getString("userId"), ChannelEnum.CLYH.getName(), briChannel.getId());
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                    logger.error("机票存入订单中心时，String转日期类出现错误");
                                }
                            }else if ("火车票".equals(order.getString("productTypeName"))){
                                dealWithMongo(order.getString("orderId"), YihaoConstants.TRAIN_MONGO_ORDER_TABLENAME, order);
                                briOrderService.saveTrain(orderCenter, orderNo, tenant, orderCenter.getString("userId"), ChannelEnum.CLYH.getName(), briChannel.getId());
                            }else if ("用车".equals(order.getString("productTypeName"))){
                                String city = orderCenter.getString("arriveCity");
                                if (StringUtil.isNotEmpty(city)){
                                    String[] split = city.split("\\|");
                                    city = split.length > 1 ? split[1] : "";
                                    orderCenter.put("arriveCity", city);
                                    orderCenter.put("cityName", city);
                                }
                                dealWithMongo(order.getString("orderId"), YihaoConstants.CAR_MONGO_ORDER_TABLENAME, order);
                                briOrderService.saveCar(orderCenter, orderNo, tenant, orderCenter.getString("userId"), ChannelEnum.CLYH.getName(), briChannel.getId());
                            }
                        }
                    }
                }
            }
        }
    }

    private JSONObject convertToJSON(CLYHConfig channelConfig) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("version", channelConfig.getVersion());
        jsonObject.put("appid", channelConfig.getAppid());
        jsonObject.put("appsecret", channelConfig.getAppsecret());
        return jsonObject;
    }

    private void dealWithMongo(String orderId, String mongoName, JSONObject orderJson) {
        logger.info("mongo查询参数【" +orderId+ ", " + mongoName + "】");
        CriteriaMap criteriaMap = new CriteriaMap();
        criteriaMap.put("orderId",orderId);
        List<JSONObject> ordersources = mongoDao.findByMap(criteriaMap, JSONObject.class, mongoName);
        if(ordersources != null && ordersources.size() > 0) {
            logger.info("订单更新存入mongo");
            mongoDao.deleteByMap(criteriaMap, mongoName);
            mongoDao.getMongoTemplate().save(orderJson, mongoName);
        }
        else {
            logger.info("订单存入mongo");
            mongoDao.getMongoTemplate().insert(orderJson, mongoName);
        }
    }
}
